package high;

import org.apache.commons.math3.geometry.spherical.oned.S1Point;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * @author 47868
 */
public class CompletableFutureTest {
    public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        mainTest(executorService);
        //thenCombineTest(executorService);
        //exceptionPrintTest(executorService);
        /*completeTest(executorService);*/
        executorService.shutdown();
    }

    public static void mainTest(ExecutorService executorService) throws ExecutionException, InterruptedException {
        Supplier<String> supplier = () -> {                 //Supplier只能用来初始化 没有参数，有返回值
            System.out.println(Thread.currentThread().getName());
            return "hello";
        };
        CompletableFuture<String> cf = CompletableFuture.supplyAsync(/*()->{    //可选supplyAsync和runAsync区别：第一个有返回值，第二个无返回值
            return "hello";
        }*/supplier,executorService);
        cf.join();
        System.out.println("cf: "+cf.get());

        Consumer<String> consumer = System.out::println;    //thenAccept参数
        // 有参数，没有返回值

        Runnable runnable = () -> {                         //thenRun的参数
            System.out.println("无入参，无返回值");
        };

        Function<String, String> function = (s)->{      //Function 用来中间操作,有参数有返回值
            System.out.println(Thread.currentThread().getName());
            return s+" CompletableFuture";
        };

        CompletableFuture<String> cf2 = cf.thenApplyAsync(/*(s)->{   //thenAccept:有入参，无返回值; thenRun:无入参，无返回值(Runable)
            return s+" CompletableFuture";
        }*/function,executorService);
        System.out.println("cf2: "+cf2.get());

        CompletableFuture cf3 = cf2.thenAccept((s)->{
            System.out.println(Thread.currentThread().getName());
            System.out.println(s);
        });
        executorService.shutdown();
    }

    public static void thenCombineTest(ExecutorService executorService) throws Exception {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(()->"hello",executorService);
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(()->" world",executorService);
        future.acceptEitherAsync(future2,(s)->{     //两个任务完成其中一个就继续执行新任务
            System.out.println(Thread.currentThread().getName());
            System.out.println(s + "...");
        });
        CompletableFuture<String> future3 = future.thenCombineAsync(future2,(s1,s2) -> s1+s2);       //将两个任务结果拼接为一个
        System.out.println(future3.getNow("没有完成..."));      //不等待任务结束，立即返回结果，参数为默认值
        Thread.sleep(1000);
    }

    public static void exceptionPrintTest(ExecutorService executorService) throws Exception {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(()->{
            try {
                //int i = 1 / 0;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            return "hello";
        },executorService);
        future.whenComplete((s,e)->{        //两个参数：一个返回值，一个异常信息
            if(s!=null){
                System.out.println(s);
            }
            else {
                System.out.println(e.getMessage());
            }
        });
        CompletableFuture<String> exceptionCF = future.exceptionally((e)->{     //只有有异常才执行
            System.out.println(e.getMessage());
            return "出现异常";
        });
        System.out.println(exceptionCF.get());          //如果没有异常，exceptionally方法中的代码没有被执行，exceptionCF的返回值与future一致
    }

    public static void completeTest(ExecutorService executorService) throws Exception {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(()->{
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return "hello";
        },executorService);
        future.complete("world");       //如果任务代码没有执行完成，放弃执行，直接返回默认值，执行完成了，无效
        System.out.println(future.get());
    }
}
